package org.yaac.server.egql.evaluator.function;

import java.util.List;

import org.yaac.server.egql.evaluator.EvaluationResult;
import org.yaac.server.egql.exception.EGQLException;
import org.yaac.server.egql.processor.ProcessData.ProcessDataRecord;
import org.yaac.shared.ErrorCode;

import com.google.appengine.api.datastore.Blob;
import com.google.appengine.api.datastore.ShortBlob;
import com.google.appengine.api.datastore.Text;

/**
 * @author Max Zhu (thebbsky@gmail.com)
 *
 */
public class LenFunction extends Function {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public void validate() throws EGQLException {
		FunctionUtil.ensureParamSize(ops, 1);
	}

	@Override
	public EvaluationResult evaluate(ProcessDataRecord record) {
		if (this.ops.isEmpty()) {
			return new EvaluationResult(null).withWarning(ErrorCode.W109);
		} else if (this.ops.size() == 1) {
			EvaluationResult r = ops.get(0).evaluate(record);
			Object payload = r.getPayload();
			
			int len = 0;
			if (payload instanceof String) {
				len = ((String)r.getPayload()).length();
			} else if (payload instanceof Text) {
				len = ((Text)r.getPayload()).getValue().length();
			} else if (payload instanceof ShortBlob) {
				len = ((ShortBlob) payload).getBytes().length;
			} else if (payload instanceof Blob) {
				len = ((Blob) payload).getBytes().length;
			} else if (payload instanceof List<?>) {
				len = ((List<?>) payload).size();
			} else {
				return r.withWarning(ErrorCode.W108);
			}
			
			// only long / double / bigdecimal is supported
			return new EvaluationResult(new Long(len), r);
		} else {
			return ops.get(0).evaluate(record).withWarning(ErrorCode.W109);
		}
	}

}
